import numpy as np
from scipy import stats
import seaborn as sns
import numpy.random as npr
import matplotlib

matplotlib.use(backend="TkAgg")
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


'''
| 分布类型                    | 是否连续 | 是否有跳跃 | 中位数表现               |
| ------------------ | ----  | ----- | ------------------- |
| 对称连续分布（如正态）        | ✅    | ❌     | **唯一中位数，一个点**       |
| 有跳变的分布（加上大量 2 和 3）| ❌    | ✅     | **中位数可能为某个跳点**      |
| 多跳变混合分布                | ❌    | ✅     | **中位数可能为一段区间内的多个值** |


'''

# 演示中位数的计算
def find_median(data):
    """找到数据的中位数和中位数区间"""
    sorted_data = np.sort(data)
    n = len(sorted_data)

    # 计算经验分布函数
    ecdf = np.arange(1, n + 1) / n

    # 找到满足 F(m) ≥ 0.5 且 F(m-0) ≤ 0.5 的点
    median_candidates = []

    for i in range(n):
        F_plus = ecdf[i]  # F(x+0)
        F_minus = ecdf[i - 1] if i > 0 else 0  # F(x-0)

        if F_plus >= 0.5 and F_minus <= 0.5:
            median_candidates.append(sorted_data[i])

    return median_candidates


# 测试不同的分布
distributions = {
    '对称连续分布': np.random.normal(0, 1, 1000),
    '有跳变的分布': np.concatenate([np.random.normal(0, 1, 800),
                                    np.ones(100) * 2, np.ones(100) * 3]),
    '多跳变分布': np.concatenate([np.random.exponential(2, 400) - 2,
                                  np.random.normal(5, 1, 300),
                                  np.ones(150) * 8, np.ones(150) * 9])
}

plt.figure(figsize=(15, 10))

for i, (name, data) in enumerate(distributions.items(), 1):
    plt.subplot(2, 2, i)

    # 计算经验分布函数
    sorted_data = np.sort(data)
    ecdf = np.arange(1, len(sorted_data) + 1) / len(sorted_data)

    # 绘制分布函数
    plt.step(sorted_data, ecdf, where='post', alpha=0.7)
    plt.axhline(y=0.5, color='r', linestyle='--', alpha=0.7, label='中位线 y=0.5')

    # 找到中位数
    medians = find_median(data)

    for median in medians:
        idx = np.where(sorted_data == median)[0][0]
        F_plus = ecdf[idx]
        F_minus = ecdf[idx - 1] if idx > 0 else 0

        plt.axvline(x=median, color='g', linestyle='-', alpha=0.7)
        plt.plot(median, F_plus, 'go', markersize=8, label=f'中位数点' if median == medians[0] else "")

        print(f"{name}:")
        print(f"  中位数候选: {median:.3f}")
        print(f"  F({median:.3f}-0) = {F_minus:.4f}")
        print(f"  F({median:.3f}+0) = {F_plus:.4f}")
        print(f"  条件检查: F(m-0)≤0.5 ({F_minus <= 0.5}), F(m)≥0.5 ({F_plus >= 0.5})")

    plt.xlabel('x')
    plt.ylabel('F(x)')
    plt.title(f'{name}的中位数')
    plt.legend()
    plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()